package com.xu.base.utils;

import java.util.concurrent.*;

/**
 * 多线程工具类
 *
 * @Author: 许乾伟
 * @Date: 2024/12/7 9:56
 */
public class ConcurrentUtils {
    /**
     * 创建一个线程池，线程数量无限制
     * @return
     */
    public static ExecutorService createCachedThreadPool() {
        return Executors.newCachedThreadPool();
    }
    /**
     * 创建指定大小的线程池
     * @param nThreads 线程池大小
     * @return
     */
    public static ExecutorService createFixedThreadPool(int nThreads) {
        return Executors.newFixedThreadPool(nThreads);
    }

    /**
     * 创建一个单线程的线程池
     * @return
     */
    public static ExecutorService createSingleThreadExecutor() {
        return Executors.newSingleThreadExecutor();
    }

    /**
     * 创建一个支持定时及周期性的任务执行的线程池
     * @param corePoolSize 线程池大小
     * @return
     */
    public static ExecutorService createScheduledThreadPool(int corePoolSize) {
        return Executors.newScheduledThreadPool(corePoolSize);
    }

    /**
     * 提交一个任务，并返回一个 Future，用于获取任务执行结果
     * @param executor
     * @param task
     * @return
     * @param <T>
     */
    public static <T> Future<T> submitTask(ExecutorService executor, Callable<T> task) {
        return executor.submit(task);
    }

    /**
     * 获取任务结果,支持超时控制
     * @param future 任务
     * @param timeout 超时时间
     * @param unit  超时时间单位
     * @return
     * @param <T>
     */
    public static <T> T getTaskResultWithTimeout(Future<T> future, long timeout, TimeUnit unit){
        try {
            return future.get(timeout,unit);
        } catch (Exception e) {
            throw new RuntimeException("任务执行超时",e);
        }
    }

    /**
     * 捕获任务执行异常
     * @param future
     * @return
     * @param <T>
     */
    public static <T> T getTaskResult(Future<T> future) {
        try {
            return future.get();
        } catch (Exception e) {
            throw new RuntimeException("任务执行失败",e);
        }
    }

    /**
     * 任务取消
     * @param future
     * @param mayInterruptIfRunning
     * @param <T>
     */
    public static <T> void cancelTask(Future<T> future,boolean mayInterruptIfRunning) {
        if (!future.isDone()){
            future.cancel(mayInterruptIfRunning);
        }
    }

    /**
     * 等待CountDownLatch完成
     * @param countDownLatch
     */
    public static void awaitCountDownLatch(CountDownLatch countDownLatch) {
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("CountDownLatch等待失败",e);
        }
    }

    /**
     * 递减CountDownLatch计数器
     * @param countDownLatch
     */
    public static void countDownLatch(CountDownLatch countDownLatch) {
        countDownLatch.countDown();
    }

    /**
     * 获取Semaphore许可
     * @param semaphore
     */
    public static void acquireSemaphore(Semaphore semaphore){
        try {
            semaphore.acquire();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Semaphore获取许可失败",e);
        }
    }

    /**
     * 释放Semaphore许可
     * @param semaphore
     */
    public static void releaseSemaphore(Semaphore semaphore){
        semaphore.release();
    }

    /**
     * 定时调度任务
     * @param executor 执行器
     * @param task 任务
     * @param delay 延迟时间
     * @param unit 延迟时间单位
     */
    public static void scheduleTask(ScheduledExecutorService executor, Runnable task, long delay, TimeUnit unit){
        executor.schedule(task,delay,unit);
    }

    /**
     * 定时执行周期性任务
     * @param executor 执行器
     * @param task 任务
     * @param initialDelay 初始延迟时间
     * @param period 周期时间
     * @param unit 时间单位
     */
    public static void scheduleTaskAtFixedRate(ScheduledExecutorService executor, Runnable task, long initialDelay, long period, TimeUnit unit){
        executor.scheduleAtFixedRate(task,initialDelay,period,unit);
    }


    /**
     * ConcurrentMap是线程安全的哈希表,可以用于高并发环境下的安全读写操作
     * 获取ConcurrentMap的值
     * @param map
     * @param key
     * @return
     * @param <K>
     * @param <V>
     */
    public static<K,V> V getConcurrentMapValue(ConcurrentMap<K,V> map,K key){
        return map.get(key);
    }

    /**
     * 添加ConcurrentMap的值
     * @param map
     * @param key
     * @param value
     * @param <K>
     * @param <V>
     */
    public static<K,V> void putConcurrentMapValue(ConcurrentMap<K,V> map,K key,V value){
        map.put(key,value);
    }
}
